package com.dragon.common.spring.openapi.httppack;

import com.dragon.common.spring.annotations.ResponseBodyPack;
import com.dragon.common.spring.annotations.ValuePack;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Optional;

/**
 * 响应体包装帮助类
 */
public class ResponsePackHelper {

    /**
     * 检查是否需要包装响应体（按照优先级） ResponseBodyPack
     * 优先级：方法 > 类 > 接口方法 > 接口类
     */
    public static boolean shouldWrapHttpResult(HandlerMethod handlerMethod) {
        // 1. 检查方法上的注解
        ResponseBodyPack methodAnnotation = AnnotationUtils.findAnnotation(
                handlerMethod.getMethod(), ResponseBodyPack.class);
        if (methodAnnotation != null) {
            return methodAnnotation.required();
        }

        // 2. 检查类上的注解
        ResponseBodyPack classAnnotation = AnnotationUtils.findAnnotation(
                handlerMethod.getBeanType(), ResponseBodyPack.class);
        if (classAnnotation != null) {
            return classAnnotation.required();
        }

        // 3. 检查接口方法上的注解
        Optional<ResponseBodyPack> interfaceMethodAnnotation = findInterfaceAnnotation(
                handlerMethod.getMethod(), ResponseBodyPack.class);
        if (interfaceMethodAnnotation.isPresent()) {
            return interfaceMethodAnnotation.get().required();
        }

        // 4. 检查接口类上的注解
        for (Class<?> interfaceClass : handlerMethod.getBeanType().getInterfaces()) {
            ResponseBodyPack interfaceAnnotation =
                    AnnotationUtils.findAnnotation(interfaceClass, ResponseBodyPack.class);
            if (interfaceAnnotation != null) {
                return interfaceAnnotation.required();
            }
        }

        return false; // 默认不包装
    }

    /**
     * 检查是否需要包装响应体（按照优先级） ValuePack
     * 优先级：方法 > 类 > 接口方法 > 接口类
     *
     * @param handlerMethod
     * @return
     */
    public static boolean shouldWrapValueResult(HandlerMethod handlerMethod) {
        // 1. 检查方法上的注解
        ValuePack methodAnnotation = AnnotationUtils.findAnnotation(
                handlerMethod.getMethod(), ValuePack.class);
        if (methodAnnotation != null) {
            return methodAnnotation.required();
        }

        // 2. 检查类上的注解
        ValuePack classAnnotation = AnnotationUtils.findAnnotation(
                handlerMethod.getBeanType(), ValuePack.class);
        if (classAnnotation != null) {
            return classAnnotation.required();
        }

        // 3. 检查接口方法上的注解
        Optional<ValuePack> interfaceMethodAnnotation = findInterfaceAnnotation(
                handlerMethod.getMethod(), ValuePack.class);
        if (interfaceMethodAnnotation.isPresent()) {
            return interfaceMethodAnnotation.get().required();
        }

        // 4. 检查接口类上的注解
        for (Class<?> interfaceClass : handlerMethod.getBeanType().getInterfaces()) {
            ValuePack interfaceAnnotation =
                    AnnotationUtils.findAnnotation(interfaceClass, ValuePack.class);
            if (interfaceAnnotation != null) {
                return interfaceAnnotation.required();
            }
        }

        return false; // 默认不包装
    }

    private static <A extends Annotation> Optional<A> findInterfaceAnnotation(
            Method method, Class<A> annotationType) {
        for (Class<?> interfaceClass : method.getDeclaringClass().getInterfaces()) {
            try {
                Method interfaceMethod = interfaceClass.getMethod(
                        method.getName(), method.getParameterTypes());
                A annotation = AnnotationUtils.findAnnotation(interfaceMethod, annotationType);
                if (annotation != null) {
                    return Optional.of(annotation);
                }
            } catch (NoSuchMethodException ignored) {
                // 接口中没有对应方法
            }
        }
        return Optional.empty();
    }
}